import GaRegExp from "../ga-reg-exp";
import { StackInfo } from "../../stack-list";
import { BranchStack, PickHandle, RuleInfo } from "../type";
import { pickHandleMap } from '.';

const judgeChildNode = function (save: Set<BranchStack>, children: StackInfo<RuleInfo>[], origin: BranchStack, str: string, index: number, char: string, length: number): boolean {
	if (children.length === 0) { return false; }

	return children.every((child) => {
		const info = child.info;
		if (info.range !== undefined) { return false; }
		const { ruleType } = info;
		if (pickHandleMap[ruleType].isNode) {
			if (index < length) {
				return !pickHandleMap[ruleType].noodHnalde(save, origin, child, str, index, char, length);
			} else {
				return true;
			}
		}
		if (ruleType === "group" || ruleType === "combo" || ruleType === "catch" || ruleType === "once" || ruleType === "flat") {
			return judgeChildNode(save, child.children, origin, str, index, char, length);
		}
		if (info.ruleType === "nested") {
			return judgeChildNode(save, info.ruleData.RegExpList.origin, origin, str, index, char, length);
		}
		return false;
	});
};

const branchPickHandle: PickHandle = {

	ruleType: "branchs",

	canCount: false,

	isNode: false,

	// [canCount=false]
	onlyEnter: (save, origin, str, index, char, length) => {
		const saveBranchStack = GaRegExp.CopyBranchStack(origin);
		const judgeBranchStack = GaRegExp.CopyBranchStack(origin);
		origin.ruleIndexStack.infoCheck.children.forEach((child, i) => {
			const list = child.children;
			if (judgeChildNode(save, list, judgeBranchStack, str, index, char, length)) {
				if (i === 0) {
					save.delete(origin);
				}
				return;
			}

			if (i === 0) {
				origin.ruleIndexStack.push(0, list);
			} else {
				const newBranch = GaRegExp.CopyBranchStack(saveBranchStack);
				newBranch.ruleIndexStack.push(0, list);
				save.add(newBranch);
			}
		});
	},

	enter: (origin, hasRange) => {
	},

	// [canCount=true]
	newExit: (enterBranch) => {

	},

	// [canCount=true]
	reenter: (enterBranch) => {
	},

	exit: (origin, hasRange) => {
	},

	// [isNode=true]
	noodHnalde: (save, origin, rule, str, index, char, length) => {
		return false;
	},

};


export default branchPickHandle;
